<script setup lang="ts">
import { computed, reactive, watch } from 'vue';
import { addJob, fetchJobDetail, updateJob } from '@/service/api';
import { useFormRules, useNaiveForm } from '@/hooks/common/form';

defineOptions({
  name: 'JobOperateDrawer'
});

interface Props {
  /** the type of operation */
  operateType: NaiveUI.TableOperateType;
  /** the edit row data */
  rowData?: Api.Dataplatform.Job | null;
}

const props = defineProps<Props>();

interface Emits {
  (e: 'submitted'): void;
}

const emit = defineEmits<Emits>();

const visible = defineModel<boolean>('visible', {
  default: false
});

const { formRef, validate, restoreValidation } = useNaiveForm();
const { defaultRequiredRule } = useFormRules();

const title = computed(() => {
  const titles: Record<NaiveUI.TableOperateType, string> = {
    add: '新增作业',
    edit: '编辑作业'
  };
  return titles[props.operateType];
});

type Model = Pick<
  Api.Dataplatform.JobEdit,
  'name' | 'jobType' | 'scheduleType' | 'scheduleConfig' | 'status' | 'projectId' | 'description'
>;

const model: Model = reactive(createDefaultModel());

function createDefaultModel(): Model {
  return {
    name: '',
    jobType: 'ETL',
    scheduleType: 'MANUAL',
    scheduleConfig: '',
    status: 1,
    projectId: undefined,
    description: ''
  };
}

type RuleKey = Extract<keyof Model, 'name' | 'jobType'>;

const rules: Record<RuleKey, App.Global.FormRule> = {
  name: defaultRequiredRule,
  jobType: defaultRequiredRule
};

const jobTypeOptions = [
  { label: 'ETL', value: 'ETL' },
  { label: 'SQL', value: 'SQL' },
  { label: '脚本', value: 'SCRIPT' }
];

const scheduleTypeOptions = [
  { label: '手动触发', value: 'MANUAL' },
  { label: '定时调度', value: 'CRON' },
  { label: '依赖调度', value: 'DEPENDENCY' }
];

const statusOptions = [
  { label: '启用', value: 1 },
  { label: '禁用', value: 0 }
];

function handleInitModel() {
  Object.assign(model, createDefaultModel());

  if (props.operateType === 'edit' && props.rowData) {
    fetchJobDetail(props.rowData.id).then(res => {
      if (res.data) {
        Object.assign(model, res.data);
      }
    });
  }
}

function closeDrawer() {
  visible.value = false;
}

async function handleSubmit() {
  await validate();
  const api = props.operateType === 'add' ? addJob : updateJob;
  const data: Api.Dataplatform.JobEdit = {
    ...model
  };
  if (props.operateType === 'edit' && props.rowData) {
    data.id = props.rowData.id;
  }
  const { error } = await api(data);
  if (!error) {
    window.$message?.success(props.operateType === 'add' ? '新增成功' : '更新成功');
    closeDrawer();
    emit('submitted');
  }
}

watch(visible, () => {
  if (visible.value) {
    handleInitModel();
    restoreValidation();
  }
});
</script>

<template>
  <NDrawer v-model:show="visible" display-directive="show" :width="640">
    <NDrawerContent :title="title" :native-scrollbar="false" closable>
      <NForm ref="formRef" :model="model" :rules="rules" label-placement="left" :label-width="100">
        <NFormItem label="作业名称" path="name">
          <NInput v-model:value="model.name" placeholder="请输入作业名称" />
        </NFormItem>
        <NFormItem label="作业类型" path="jobType">
          <NSelect v-model:value="model.jobType" :options="jobTypeOptions" placeholder="请选择作业类型" />
        </NFormItem>
        <NFormItem label="调度类型" path="scheduleType">
          <NSelect v-model:value="model.scheduleType" :options="scheduleTypeOptions" placeholder="请选择调度类型" />
        </NFormItem>
        <NFormItem v-if="model.scheduleType === 'CRON'" label="调度配置" path="scheduleConfig">
          <NInput
            v-model:value="model.scheduleConfig"
            type="textarea"
            :rows="3"
            placeholder="请输入Cron表达式，如: 0 0 2 * * ?"
          />
        </NFormItem>
        <NFormItem label="状态" path="status">
          <NRadioGroup v-model:value="model.status">
            <NRadio v-for="item in statusOptions" :key="item.value" :value="item.value" :label="item.label" />
          </NRadioGroup>
        </NFormItem>
        <NFormItem label="描述" path="description">
          <NInput v-model:value="model.description" type="textarea" :rows="3" placeholder="请输入描述" />
        </NFormItem>
      </NForm>
      <template #footer>
        <NSpace justify="end">
          <NButton @click="closeDrawer">取消</NButton>
          <NButton type="primary" @click="handleSubmit">确定</NButton>
        </NSpace>
      </template>
    </NDrawerContent>
  </NDrawer>
</template>

<style scoped></style>
